package com.google.code.maven.plugin.http.client.config;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.maven.plugin.MojoExecutionException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import com.google.code.maven.plugin.http.client.transformer.Transformer;

/**
 * 
 * @author Nadim Benabdenbi
 * @version 1.0
 * @since JDK1.6
 * 
 */
public class TransformerConfiguration implements ConfigurationBean<Transformer<?, ?>> {

	protected static final AtomicInteger id = new AtomicInteger();

	/**
	 * @parameter
	 * @required
	 */
	private String className;

	/**
	 * wrapped transformer properties
	 * 
	 * @parameter
	 */
	private BeanProperty properties[];

	public Transformer<?, ?> build(DefaultListableBeanFactory factory) throws MojoExecutionException {
		try {
			BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Class.forName(className));
			if (properties != null) {
				for (BeanProperty property : properties) {
					property.validate();
					if (property.getValue() != null) {
						builder.addPropertyValue(property.getName(), property.getValue());
					} else if (property.getRef() != null) {
						builder.addPropertyReference(property.getName(), property.getRef());
					} else if (property.getRef() != null) {
						builder.addPropertyValue(property.getName(), property.getValue());
					} else if (property.getArray() != null) {
						builder.addPropertyValue(property.getName(), property.getArray());
					} else if (property.getList() != null) {
						builder.addPropertyValue(property.getName(), property.getList());
					} else if (property.getSet() != null) {
						builder.addPropertyValue(property.getName(), property.getSet());
					} else if (property.getMap() != null) {
						builder.addPropertyValue(property.getName(), property.getMap());
					} else if (property.getProperties() != null) {
						builder.addPropertyValue(property.getName(), property.getProperties());
					}
				}
			}
			String beanId = className + "." + id.incrementAndGet();
			factory.registerBeanDefinition(beanId, builder.getBeanDefinition());
			Transformer<?, ?> result = factory.getBean(beanId, Transformer.class);
			return result;
		} catch (BeansException be) {
			throw new MojoExecutionException("failed to set up transformer", be);
		} catch (ClassNotFoundException cnfe) {
			throw new MojoExecutionException("transformer class not found [" + className + "]", cnfe);
		}
	}

	/**
	 * @return the className
	 */
	public String getClassName() {
		return className;
	}

	/**
	 * @param className the className to set
	 */
	public void setClassName(String className) {
		this.className = className;
	}

	/**
	 * @return the properties
	 */
	public BeanProperty[] getProperties() {
		return properties;
	}

	/**
	 * @param properties the properties to set
	 */
	public void setProperties(BeanProperty[] properties) {
		this.properties = properties;
	}

}
